package  com.ruoyi.common.utils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.commons.lang3.StringUtils;

import com.ruoyi.common.utils.TimeUtil;

public class PlanGenner {

	/**
	 * 计算周转金
	 * 
	 * @param planMoney
	 * @param daytime
	 * @param times
	 * @return
	 * @throws Exception
	 */
	public static BigDecimal calculateZhj(String planMoney, String daytime, String times, BigDecimal feilv)
			throws Exception {
		String[] times_ = daytime.split(",");
		String oncemoney = "1";
		BigDecimal planMoney_ = new BigDecimal(planMoney);
		BigDecimal oncemoney_ = new BigDecimal(oncemoney);
		BigDecimal daytime_ = new BigDecimal(times);
		BigDecimal times_length = new BigDecimal(times_.length);
		BigDecimal totaltimes = times_length.multiply(daytime_);
		BigDecimal onemoretime = new BigDecimal(oncemoney);// 首刷费率
		BigDecimal totaltimes_money = oncemoney_.multiply(daytime_).multiply(times_length).add(onemoretime);
		BigDecimal totalRateMoney = feilv.multiply(planMoney_);
		BigDecimal total_rate = totaltimes_money.add(totalRateMoney);
		BigDecimal avgmoney = planMoney_.divide(totaltimes, 0, BigDecimal.ROUND_DOWN);
		BigDecimal total_free = totalRateMoney.add(totaltimes_money);
		BigDecimal free_free = feilv.multiply(total_free).add(new BigDecimal("0.01").multiply(totaltimes));
		BigDecimal total_zhj = avgmoney.add(total_rate).add(free_free);
		BigDecimal total_zhouzhuanjin = total_zhj.setScale(2, BigDecimal.ROUND_HALF_UP);
		return total_zhouzhuanjin;
	}

	/**
	 * 生产一刷一还计划
	 * 
	 * @param planMoney 待还款金额
	 * @param daytime 时间字符例如"2019-05-03,2019-05-04"
	 * @param times 还款次数 1每天一次  |2每天两次   |3每天3次
	 * @return
	 * @throws Exception
	 */
	public static Map<String, Object> grennerPlan(String planMoney, String daytime, String times, BigDecimal feilv)
			throws Exception {
		Map<String, Object> map = new HashMap<>();
		System.out.println("::daytime::"+daytime);
		String[] times_ = daytime.split(",");
		String oncemoney = "1";
		BigDecimal planMoney_ = new BigDecimal(planMoney);
		BigDecimal oncemoney_ = new BigDecimal(oncemoney);
		BigDecimal daytime_ = new BigDecimal(times);
		BigDecimal times_length = new BigDecimal(times_.length);
		BigDecimal totaltimes = times_length.multiply(daytime_);
		BigDecimal onemoretime = new BigDecimal(1);// 首刷费率
		BigDecimal totaltimes_money = oncemoney_.multiply(daytime_).multiply(times_length).add(onemoretime);
		BigDecimal totalRateMoney = feilv.multiply(planMoney_);
		BigDecimal total_rate = totaltimes_money.add(totalRateMoney);
//		double total_free = total_rate.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
		int starthour = 7;
		int endhour = 21;
		if (times.equals("1")) {
			starthour = 9;
			endhour = 16;
		} else if (times.equals("2")) {
			starthour = 9;
			endhour = 19;
		}
		int daytimeshours = endhour - starthour;
		// 每天总共的交易次数（包括还款、消费）
		int daysalepaycount = Integer.parseInt(times) * 2;
		int hoursept = daytimeshours / daysalepaycount;
		BigDecimal avgmoney = planMoney_.divide(totaltimes, 0, BigDecimal.ROUND_DOWN);
//		double total_zhouzhuanjin = avgmoney.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
//		System.out.println("计划还款：planMoney_ " + planMoney_);
//		System.out.println("费率手续费：totalRateMoney " + totalRateMoney);
//		System.out.println("次数费：totaltimes_money " + totaltimes_money);
		BigDecimal total_free = totalRateMoney.add(totaltimes_money);
//		System.out.println("共计手续费：total_free " + total_free);
//		System.out.println("平均费用：avgmoney " + avgmoney);
		BigDecimal free_free = feilv.multiply(total_free).add(new BigDecimal("0.01").multiply(totaltimes));
		BigDecimal total_zhj = avgmoney.add(total_rate).add(free_free);
		double total_zhouzhuanjin = total_zhj.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
//		System.out.println("共计周转金：total_zhouzhuanjin " + total_zhouzhuanjin);
		// 先排序
//		System.out.println("当天交易可用小时数" + daytimeshours);
//		System.out.println("每天交易次数" + daysalepaycount);
		int totalCount = totaltimes.add(totaltimes).intValue();
//		System.out.println("本次计划共计交易次数:" + (totalCount+1));
//		System.out.println("时间步长" + hoursept);
		List<String> list = sortDays(daytime);
		Date salenow = new Date();
		Date randomDate = randomDate(TimeUtil.latterhour(salenow, 1), TimeUtil.latterhour(salenow, 2));
		List<PlanGennerItem> items = new ArrayList<>();
		PlanGennerItem item = new PlanGennerItem();
		item.setGroup(0);
		item.setMoney(total_zhouzhuanjin + "");
		item.setTime(salenow);
		item.setType("sale");
		items.add(item);
		item = new PlanGennerItem();
		item.setGroup(0);
		item.setMoney(avgmoney + "");
		item.setTime(randomDate);
		item.setType("payment");
		items.add(item);
//		System.out.println("立即消费 " + sf.format(salenow) + ",消费金额 " + total_zhouzhuanjin);
//		System.out.println("立即还款 " + sf.format(randomDate) + ",还款金额 " + avgmoney);
		BigDecimal topaymoney = planMoney_.subtract(avgmoney);
		BigDecimal last = topaymoney;
		int card = avgmoney.intValue();
		double fudong = 0.1;
		topaymoney = topaymoney.add(topaymoney.multiply(new BigDecimal(fudong)));
		avgmoney = topaymoney.divide(totaltimes, 0, BigDecimal.ROUND_DOWN);
		int tongdao = 0;
		int truemoneypay = 0;
		int dayindex = 1;
		int dan_index = 0;
		double sale_min = 0.8;
		double sale_max = 1;
		double pay_min = sale_min - fudong;
		double pay_max = sale_min;
		for (String day : list) {
			int index = starthour;
			int index_END = (index + hoursept - 1);
			int type = 1;
			dan_index = 1;
			for (int i = 1; i <= daysalepaycount; i++) {
				dan_index++;
				type++;
				dayindex++;
				String _start = day + " " + index + ":00:00";
				String _end = day + " " + index_END + ":50:00";
				randomDate = randomDate(_start, _end);
				index = index_END + 1;
				index_END = index_END + hoursept;
				if (dayindex % 2 == 0) {
					sale_min = pay_min;
					sale_max = pay_max;
					pay_min = sale_min;
					pay_max = sale_max;
				} else {
					pay_min = sale_min;
					pay_max = sale_max;
					sale_min = pay_min;
					sale_max = pay_max;
				}
				if ((dayindex + 1) % 3 == 0) {
					sale_min = 0.9;
					sale_max = 1;
					pay_min = 0.9;
					pay_max = 1;
				}
				String _type = "";
				int current = 0;

				if (type % 2 == 0) {
					int min = avgmoney.multiply(new BigDecimal(sale_min)).intValue();
					int max = avgmoney.multiply(new BigDecimal(sale_max)).intValue();
					Random random = new Random();
					current = random.nextInt(max) % (max - min + 1) + min;
					_type = "sale";
					if (card < current) {
						current = random.nextInt(card) % (card - min + 1) + min;
					}
					tongdao += current;
					card -= current;
				} else {
					int min = avgmoney.multiply(new BigDecimal(pay_min)).intValue();// 最低八五折起步
					int max = avgmoney.multiply(new BigDecimal(pay_max)).intValue();
					Random random = new Random();
					current = random.nextInt(max) % (max - min + 1) + min;
					_type = "payment";
					if (tongdao < current) {
						current = random.nextInt(tongdao) % (tongdao - min + 1) + min;
					}
					if (dayindex == totalCount + 1) {
						current = tongdao;
					}
					truemoneypay += current;
					tongdao -= current;
					card += current;
				}
				if (tongdao < 0 || card < 0) {
					throw new Exception("请调整还款金额或还款日期重新计算！");
				}

				item = new PlanGennerItem();
				item.setGroup(dan_index);
				item.setMoney(current + "");
				item.setTime(randomDate);
				item.setType(_type);
				items.add(item);
//				System.out.println(_type + sf.format(randomDate) + ",金额 " + current + " 通道结余 " + tongdao + " 账户余额 " + card);
			}
		}
		int endmoney = last.intValue() - truemoneypay;
		if (endmoney > 0)
			throw new Exception("请调整还款金额或还款日期重新计算！");
		for (int is = items.size() - 2; is < items.size(); is++) {
			PlanGennerItem planItem = items.get(is);
			planItem.setMoney((Integer.parseInt(planItem.getMoney()) + endmoney) + "");
		}
		BigDecimal saletotal = new BigDecimal(0);
		BigDecimal paytotal = new BigDecimal(0);
		int group = 0;
		for (PlanGennerItem it : items) {
			group++;
			BigDecimal thismoney = new BigDecimal(it.getMoney());
			if (it.getType().equals("sale")) {
				BigDecimal thisfree = thismoney.multiply(feilv);
				BigDecimal thisflv = thisfree.add(onemoretime);
				BigDecimal add = thismoney.add(thisflv);
				saletotal = saletotal.add(add);
				it.setGroup(group);
			} else {
				group--;
				paytotal = paytotal.add(thismoney);
				it.setGroup(group);
			}
		}
		saletotal = new BigDecimal(0);
		paytotal = new BigDecimal(0);
		BigDecimal small = total_zhj;
		for (PlanGennerItem it : items) {
			BigDecimal thismoney = new BigDecimal(it.getMoney());
			if (small.compareTo(thismoney) > 0)
				small = thismoney;
			if (it.getType().equals("sale")) {
				saletotal = saletotal.add(thismoney);
			} else {
				paytotal = paytotal.add(thismoney);
			}
//			System.out.println(it.toString());
		}
		System.out.println("最小消费金额：" + (small));
		System.out.println("最大消费金额：" + total_zhouzhuanjin);
		System.out.println("最终消费金额：" + (saletotal));
		System.out.println("最终还款金额：" + (paytotal));
		System.out.println("单笔手续费：" + (totaltimes_money));
		System.out.println("费率手续费：" + (totalRateMoney));
		System.out.println("手续费的手续费：" + (free_free));
		System.out.println("费用总和：" + (totalRateMoney.add(free_free).add(totaltimes_money)));
		map.put("items", items);
		map.put("times_money", com.ruoyi.common.utils.StringUtils.twoDecimals(totaltimes_money));
		map.put("saletotal", com.ruoyi.common.utils.StringUtils.twoDecimals(saletotal));
		map.put("paytotal", com.ruoyi.common.utils.StringUtils.twoDecimals(paytotal));
		map.put("rate_money", com.ruoyi.common.utils.StringUtils.twoDecimals(totalRateMoney));
		map.put("free_free", com.ruoyi.common.utils.StringUtils.twoDecimals(free_free));
		map.put("total_zhj", com.ruoyi.common.utils.StringUtils.twoDecimals(total_zhj));
		map.put("total_free", com.ruoyi.common.utils.StringUtils.twoDecimals(totalRateMoney.add(free_free).add(totaltimes_money)));
		map.put("sale_min",  com.ruoyi.common.utils.StringUtils.twoDecimals(small));
		map.put("sale_max",  com.ruoyi.common.utils.StringUtils.twoDecimals(total_zhj));
		SimpleDateFormat sff = new SimpleDateFormat("yyyy/MM/dd");
		String starttime = sff.format(new Date());
		String endtime = list.get(list.size() - 1);
		sff = new SimpleDateFormat("yyyy-MM-dd");
		Date endtime1 = sff.parse(endtime);
		sff = new SimpleDateFormat("yyyy/MM/dd");
		endtime = sff.format(endtime1);
		map.put("plan_time", starttime + " - " + endtime);

		return map;
	}

	/**
	 * 生成随机时间
	 * 
	 * @param beginDate
	 * @param endDate
	 * @return
	 */
	private static Date randomDate(String beginDate, String endDate) {
		try {
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Date start = format.parse(beginDate);// 构造开始日期
			Date end = format.parse(endDate);// 构造结束日期
			// getTime()表示返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
			if (start.getTime() >= end.getTime()) {
				return null;
			}
			long date = random(start.getTime(), end.getTime());
			return new Date(date);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private static Date randomDate(Date start, Date end) {
		try {
			if (start.getTime() >= end.getTime()) {
				return null;
			}
			long date = random(start.getTime(), end.getTime());
			return new Date(date);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private static long random(long begin, long end) {
		long rtn = begin + (long) (Math.random() * (end - begin));
		// 如果返回的是开始时间和结束时间,则递归调用本函数查找随机值
		if (rtn == begin || rtn == end) {
			return random(begin, end);
		}
		return rtn;
	}

	public static String addDateMinut(String day, int hour) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = null;
		try {
			date = format.parse(day);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		if (date == null)
			return "";
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.HOUR, hour);// 24小时制
		date = cal.getTime();
		cal = null;
		return format.format(date);
	}

	public static void main(String[] args) throws ParseException {
		String bankName = "华夏银行";
		Map<String, String> acqmap = new LinkedHashMap<>();
		//中国工商银行中国农业银行中国建设银行中国银行中国邮政储蓄银行招商银行兴业银行中国光大银行广发银行平安银行中国民生银行浦发银行中信银行上海银行北京银行交通银行华夏银行
		acqmap.put("8084", ";华夏银行");
		acqmap.put("8079", ";华夏银行");
		String acqcode = searchAcqCode(acqmap, bankName);
		if (acqcode == null) {
			System.out.println("SORRY，暂时无法合适通道提供！");
		} else {
			System.out.println("匹配到合适的通道了：" + acqcode);
		}
		String dat = "2019-5-01,2019-4-10,2019-4-11,2019-5-9,2019-4-6";
		List<String> list = sortDays(dat);
		for (String day : list) {
			System.out.println(day);
		}
	}
	
	/**
	 * 对时间进行排序
	 * @param days
	 * @return
	 * @throws ParseException
	 */
	private static List<String> sortDays(String days) throws ParseException {
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		String[] times_ = days.split(",");
		List<Date> list_days = new ArrayList<Date>();
		List<String> list_result = new ArrayList<String>();
		for (String day : times_) {
			list_days.add(sf.parse(day));
		}
		Collections.sort(list_days);
		for (Date day : list_days) {
			list_result.add(sf.format(day));
		}
		return list_result;
	}

	/**
	 * 寻找合适通道提供服务
	 * 
	 * @param acqmap   通道集合
	 * @param bankName 银行名称
	 * @return
	 */
	public static String searchAcqCode(Map<String, String> acqmap, String bankName) {
		int total = acqmap.size();
		int error_index = 0;
		int success_index = 0;
		String success_code = "";
		Map<String, String> acqmap_ = new LinkedHashMap<String, String>();
		for (Map.Entry<String, String> entry : acqmap.entrySet()) {
//			System.out.println("entry.getKey():"+entry.getKey());
//			System.out.println("entry.getValue():"+entry.getValue());
			String value = entry.getValue();
			if(StringUtils.isBlank(value)) {
				success_index++;
				success_code += entry.getKey()+",";
				continue;
			}
			String banks[] = value.split(";");
			if (banks.length > 1) {
//				System.out.println("发现需要屏蔽的"+entry.getKey());
				String nosupportbank = banks[1];
				if (nosupportbank.contains(bankName)) {
					error_index++;
				}else {
//					System.out.println("没找到屏蔽，加吧"+entry.getKey());
					acqmap_.put(entry.getKey(),value);
				}
			}else {
//				System.out.println("无需屏蔽，直接干"+entry.getKey());
				acqmap_.put(entry.getKey(),value);
			}
		}
//		System.out.println(total+":error_index:"+error_index);
		if (error_index == total) {
			return null;
		}
		for (Map.Entry<String, String> entry : acqmap_.entrySet()) {
//			System.out.println("第二轮筛选开始："+entry.getValue());
			if (entry.getValue().length() > 0) {
				String banks[] = entry.getValue().split(";");
				String supportbank = banks[0];
//				System.out.println("supportbank:"+supportbank);
				if (supportbank.contains(bankName)) {
//					System.out.println("恭喜被选中了entry.getKey()："+entry.getKey());
					success_index++;
					success_code += entry.getKey() + ",";
				}
//				System.out.println("1选择了："+success_code);
				if (StringUtils.isBlank(supportbank) && banks.length > 1) {
//					System.out.println("是否需要二次屏蔽：");
					String nosupportbank = banks[1];
					if (!nosupportbank.contains(bankName)) {
						success_index++;
						success_code += entry.getKey() + ",";
					}
				}
//				System.out.println("2选择了："+success_code);
			}else {
				success_index++;
				success_code += entry.getKey() + ",";
//				System.out.println("最后一次直接干："+entry.getKey());
			}
		}
		if (success_index > 0)
			return success_code;
		return null;
	}
	

}
